﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Form1.cs" company="melcoprog">
//   Copyright (c) melcoprog. All rights reserved.
// </copyright>
// <summary>
//   The form.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ESheep
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Linq;
    using System.Windows.Forms;
    using Creature;

    using CreatureSheep.AI;
    using CreatureSheep.CreatureState;
    using CreatureSheep.CreatureStates;
    using CreatureSheep.CreatureStates.Hooked;
    using CreatureSheep.CreatureStates.Idle;
    using CreatureSheep.CreatureStates.Pissing;
    using CreatureSheep.CreatureStates.Run;
    using CreatureSheep.CreatureStates.Walk;

    using ESheep.Sheep.World;

    using Microsoft.Win32;

    /// <summary>
    /// The form 1.
    /// </summary>
    public partial class Form1 : Form
    {
        /// <summary>
        /// The sheep.
        /// </summary>
        private readonly CreatureSheep.Sheep esheep;

        /// <summary>
        /// Initializes a new instance of the <see cref="Form1"/> class.
        /// </summary>
        public Form1()
        {
            this.InitializeComponent();

            // Set our control's size to be the same as the bitmap
            this.Width = 55;
            this.Height = 75;

            // No border
            this.FormBorderStyle = FormBorderStyle.None;

            try
            {
                var creatureStates = new List<ICreatureState>();

                var bmp = new Bitmap(Properties.Resources.Image1);

                IBorder border = new Border(Screen.AllScreens.Select(a => a.WorkingArea));

                IStateRepository idleRepository = new IdleRepository(bmp);
                ICreatureState idleCreatureState = new Idle(idleRepository, border);
                creatureStates.Add(idleCreatureState);

                IStateRepository runRepository = new RunRepository(bmp);
                ICreatureState runCreatureState = new Run(runRepository, border);
                creatureStates.Add(runCreatureState);

                IStateRepository pissingRepository = new PissingRepository(bmp);
                ICreatureState pissingCreatureState = new Pissing(pissingRepository, border);
                creatureStates.Add(pissingCreatureState);

                IStateRepository walkRepository = new WalkRepository(bmp);
                ICreatureState walkCreatureState = new Walk(walkRepository, border);
                creatureStates.Add(walkCreatureState);

                IStateMachine stateMachine = new ArtificialIntelligence(creatureStates);

                IStateRepository hookedRepository = new HookedRepository(bmp);
                ICreatureState hookedCreatureState = new Hooked(hookedRepository, border);

                this.esheep = new CreatureSheep.Sheep(stateMachine, runCreatureState, hookedCreatureState);

                SystemEvents.SessionSwitch += this.SystemEventsSessionSwitch;

                this.timer1.Start();
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.ToString());
                this.Close();
            }
        }

        /// <summary>
        /// The system events session switch.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void SystemEventsSessionSwitch(object sender, SessionSwitchEventArgs e)
        {
            if (e.Reason == SessionSwitchReason.SessionLock)
            {
                this.timer1.Stop();
            }
            else if (e.Reason == SessionSwitchReason.SessionUnlock)
            {
                this.timer1.Start();
            }
        }

        /// <summary>
        /// The timer tick.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void Timer1Tick(object sender, EventArgs e)
        {
            try
            {
                var step = this.esheep.MakeStep();
                if (step != null)
                {
                    this.pictureBox1.Image = (Bitmap)step.NewImage;
                    this.Region = new Region((GraphicsPath)step.NewMask);

                    this.Left = (int)step.NewX;
                    this.Top = (int)step.NewY;
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.ToString());
                this.Close();
            }
        }

        /// <summary>
        /// The picture box mouse down.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void PictureBox1MouseDown(object sender, MouseEventArgs e)
        {
            try
            {
                this.esheep.Hook();
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.ToString());
                this.Close();
            }
        }

        /// <summary>
        /// The picture box mouse up.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void PictureBox1MouseUp(object sender, MouseEventArgs e)
        {
            try
            {
                this.esheep.UnHook();

                if (e.Button == MouseButtons.Right)
                {
                    this.Close();
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.ToString());
                this.Close();
            }
        }
    }
}
